package com.yuedou.jylt.http;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;

import androidx.annotation.NonNull;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yuedou.jylt.constant.Const;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * <pre>
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 16/12/08
 *     desc  : Utils初始化相关
 * </pre>
 */
public class RequestUtils {

    private static Context context;

    private RequestUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 初始化工具类
     *
     * @param context 上下文
     */
    public static void init(Context context) {
        RequestUtils.context = context.getApplicationContext();
    }

    /**
     * 获取ApplicationContext
     *
     * @return ApplicationContext
     */
    public static Context getContext() {
        if (context != null) return context;
        throw new NullPointerException("u should init first");
    }

    private static Retrofit retrofit;

    /**
     * 返回Retrofit
     */
    public static Retrofit getRetrofit() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(Const.BASE_URL) //指定网络请求的baseUrl
                    .addConverterFactory(new NullOnEmptyConverterFactory())//返回内容为空的异常修复
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create(buildGson()))//返回的数据通过Gson解析
//                    .client(getClient())
                    .build();
        }
        return retrofit;
    }

    public static Retrofit getRetrofit(String sessionID) {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .client(genericClient(sessionID))
                    .baseUrl(Const.BASE_URL) //指定网络请求的baseUrl
                    .addConverterFactory(new NullOnEmptyConverterFactory())//返回内容为空的异常修复
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create(buildGson()))//返回的数据通过Gson解析
                    .build();
        }
        return retrofit;
    }

    private static OkHttpClient genericClient(final String sessionID) {

        return new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(@NonNull Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("Cookie", "JSESSIONID=" + sessionID)
                                .build();
                        return chain.proceed(request);
                    }
                })
                .build();
    }

    /**
     * 初始化 OkHttpClient
     */
    private static OkHttpClient getClient() {

        OkHttpClient.Builder client = new OkHttpClient().newBuilder();

        client.interceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                // 获取 Cookie
                Response originalResponse = chain.proceed(chain.request());
                if (!originalResponse.headers("Set-Cookie").isEmpty()) {
                    HashSet<String> cookies = new HashSet<>(originalResponse.headers("Set-Cookie"));
//                    KLog.d("获取Cookie：" + cookies);
                    RequestUtils.getPreference().edit().putStringSet("cookie", cookies).apply();
                }
                return originalResponse;
            }
        });
        client.interceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                // 设置 Cookie
                Request.Builder builder = chain.request().newBuilder();
                HashSet<String> preferences = (HashSet) RequestUtils.getPreference().getStringSet("cookie", null);
                if (preferences != null) {
                    for (String cookie : preferences) {
                        builder.addHeader("Cookie", cookie);
//                        KLog.d("设置Cookie", cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
                    }
                }
                return chain.proceed(builder.build());
            }
        });

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
//                KLog.d("okhttp", message);
            }
        });
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);//Level中还有其他等级
        client.addInterceptor(logging);
        return client.build();
    }

    private static SharedPreferences preferences;

    public static SharedPreferences getPreference() {
        if (preferences == null) {
            preferences = context.getSharedPreferences(Const.USER, Activity.MODE_PRIVATE);
        }
        return preferences;
    }


    public static Gson buildGson() {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .registerTypeAdapter(new TypeToken<Map<String, Object>>(){}.getType(), new GsonTypeAdapter())
                .create();

//        Gson gson = new GsonBuilder()
//                    .setDateFormat("yyyy-MM-dd HH:mm:ss")
//                    .registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
//                    .registerTypeAdapter(int.class, new IntegerDefault0Adapter())
//                    .registerTypeAdapter(HashMap.class, new JsonDeserializer<HashMap>() {
//                        @Override
//                        public HashMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//                            HashMap<String, Object> resultMap = new HashMap<>();
//                            JsonObject jsonObject = json.getAsJsonObject();
//                            Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
//                            for (Map.Entry<String, JsonElement> entry : entrySet) {
//                                resultMap.put(entry.getKey(), entry.getValue());
//                            }
//                            return resultMap;
//                        }
//                    })
//                .create();
        return gson;
    }
}
